import { E_GameBaseAttr } from "../defs/com/E_GameBaseAttr";
import { CDMathx } from "../excel/CDMathx";
import { CDMonster, E_CDMonster } from "../excel/CDMonster";
import { CDUnit } from "../excel/CDUnit";
import { CEMath } from "../excel_extend/CEMath";
import { LanguageUtils } from "../../utils/LanguageUtils";
import { SDBattle } from "./SDBattle";
import { SDPet } from "./SDPet";
import { SDSkill } from "./SDSkill";


/**
 * 数据-怪物
 */
export abstract class SDMonster {

    /**
     * 获取怪物模型
     * @param monster 
     */
    public static getMonsterSpineUrl(monster: number | CDMonster): string {
        const monsterConfig = (monster instanceof CDMonster) ? monster : CDMonster.getData(monster);
        if (monsterConfig) {
            const unitConfig = CDUnit.getData(monsterConfig.unitID);
            if (unitConfig && unitConfig.model && unitConfig.model.length > 0) {
                const url = unitConfig.model;
                return url + '/' + url;
            }
        }

        //没有的先随机一个
        const monsterSpineId = monsterConfig.id % 16;
        const url = 'monster_' + (monsterSpineId > 9 ? monsterSpineId : ('0' + monsterSpineId));
        return url + '/' + url;
    }


    /**
     * 获取怪物名
     * @param monster 
     * @returns 
     */
    public static getMonsterName(monster: number | CDMonster): string {
        const monsterConfig = (monster instanceof CDMonster) ? monster : CDMonster.getData(monster);
        if (monsterConfig) {
            const unitConfig = CDUnit.getData(monsterConfig.unitID);
            if (unitConfig && unitConfig.model && unitConfig.model.length > 0) {
                return LanguageUtils.getV(unitConfig.name);
            }
        }

        //没有的先随机一个
        return 'monster_' + monster;
    }


    /**
     * 获取技能和等级
     * @param monster 
     * @param containPet 包含宠物
     * @param outs
     * @returns 
     */
    public static getSkillIdLevel(
        monster: number | CDMonster,
        containPet = true,
        outs: number[] = []
    ): number[] {

        const skillIdLevels: number[] = outs;
        const monsterConfig = (monster instanceof CDMonster) ? monster : CDMonster.getData(monster);

        skillIdLevels.length = 0;

        if (monsterConfig) {
            const unitConfig = CDUnit.getData(monsterConfig.unitID);
            if (unitConfig) {
                //普通技能
                if (unitConfig.nomarl_skill > 0) {
                    skillIdLevels.push(unitConfig.nomarl_skill, monsterConfig.activeSkillLv);
                }
                //主动技能
                {
                    const activeSkill = unitConfig.activeSkill;
                    for (let i = 0, len = activeSkill.length; i < len; i++) {
                        if (activeSkill[i] > 0) {
                            skillIdLevels.push(activeSkill[i], monsterConfig.activeSkillLv);
                        }
                    }
                }
                //被动技能
                {
                    const passiveSkill = unitConfig.passiveSkill;
                    for (let i = 0, len = passiveSkill.length; i < len; i++) {
                        if (passiveSkill[i] > 0) {
                            skillIdLevels.push(passiveSkill[i], monsterConfig.passiveSkillLv);
                        }
                    }
                }
            }

            //宠物的被动技能
            if (containPet) {
                SDPet.addPetSkillIdLevelByMonsterConfig(monsterConfig, skillIdLevels);
            }
        }

        return skillIdLevels;
    }


    /**
     * 获取属性值
     * @param monster 
     * @param skillIdLevels 
     * @param containPet 包含宠物
     * @param outs 
     * @returns 
     */
    public static getMathValues(
        monster: number | CDMonster,
        skillIdLevels: number[] = null,
        containPet = true,
        outs: number[] = []
    ): number[] {

        const monsterConfig = (monster instanceof CDMonster) ? monster : CDMonster.getData(monster);
        const mathConfig = monsterConfig ? CDMathx.getData(monsterConfig.math) : null;

        //基础属性
        const mathValues: number[] = outs;
        if (mathConfig) {
            for (let i = 0, len = E_GameBaseAttr.EnumCount; i < len; i++) {
                const idx = CEMath.getExcelTypeXXXByGameAttrType(i);
                mathValues[i] = mathConfig.getAttr(idx);
            }
        }
        else {
            for (let i = 0, len = E_GameBaseAttr.EnumCount; i < len; i++) {
                mathValues[i] = 0;
            }
        }

        //宠物的基础属性
        if (containPet && monsterConfig) {
            for (let i = E_CDMonster.pet_1; i <= E_CDMonster.pet_4; i++) {
                const petConfigList = monsterConfig.getAttr(i);
                SDPet.addPetMathByPetConfigList(petConfigList, mathValues);
            }
        }

        //技能增加的math
        if (skillIdLevels) {
            for (let i = 0, len = skillIdLevels.length; i < len; i += 2) {
                SDSkill.addGameBaseAttr(skillIdLevels[i], skillIdLevels[i + 1], mathValues, true);
            }
        }

        return mathValues;
    }


    /**
     * 获取战力
     * @param monster 
     */
    public static getFightScore(
        monster: number | CDMonster
    ): number {
        const monsterConfig = (monster instanceof CDMonster) ? monster : CDMonster.getData(monster);
        if (!monsterConfig) {
            return 0;
        }

        const skillIdLevels = this.getSkillIdLevel(monsterConfig);
        const mathValues = this.getMathValues(monsterConfig, skillIdLevels);
        const v = SDBattle.getFightScore(mathValues);

        return v;
    }


}
